package com.lute.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.json.JSONArray;
import org.springframework.security.oauth2.common.json.JSONException;
import org.springframework.security.oauth2.common.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.lute.model.Admin;
import com.lute.model.Client;
import com.lute.model.ClientAdmin;
import com.lute.model.ClientAdminProfile;
import com.lute.model.ClientProfile;
import com.lute.model.Employee;
import com.lute.model.Role;
import com.lute.model.User;
import com.lute.model.UserEntitlement;
import com.lute.utils.LdapDAO;
import com.lute.utils.ServerErrorResponse;

@Controller
public class AddNewUserServlet {
	
	@Autowired
	LdapDAO ldap;
	
	@RequestMapping(value="/addUser", method = RequestMethod.POST,headers = "Content-type=application/json")
	public @ResponseBody String addUser(@RequestBody String dataJSON, HttpServletRequest request) throws JSONException {
		
		String result = "";
		JSONArray clientIds = null;
		String userLogin;
		String userRole;
		String defaultClientId;
		JSONObject jsonReq;
		JSONObject jsonRes = new JSONObject();
		
		HttpSession session = request.getSession(false);
		if(session == null) {
			jsonRes.put("result", ServerErrorResponse.USER_NOT_LOGGED_IN.toString());
			result = jsonRes.toString();
			return result;
		}
		
		try {
			jsonReq = new JSONObject(dataJSON);
			userLogin = jsonReq.getString("userLogin");
			userRole = jsonReq.getString("userRole");
			defaultClientId = jsonReq.getString("defaultClientId");
		} catch(JSONException e) {
			jsonRes.put("result", ServerErrorResponse.MALFORMED_REQUEST.toString());
			result = jsonRes.toString();
			return result;
		}
		
		/* check if json data was not malformed */
		if((jsonReq.isNull("clientIds")) && (jsonReq.isNull("userLogin")) && (jsonReq.isNull("userRole"))
				&&(jsonReq.isNull("defaultClientId"))) {
			jsonRes.put("result",ServerErrorResponse.MALFORMED_REQUEST.toString());
			result = jsonRes.toString();
			return result;
		}
		
		if(!(jsonReq.isNull("clientIds"))) {
			clientIds = jsonReq.getJSONArray("clientIds");
		}
		
		int sessionUserId = (Integer)session.getAttribute("sessionUserId");
		String role = (String)session.getAttribute("role");
		
		/* check  authorization */
		if(!(role.equals("admin"))) {
			jsonRes.put("result", ServerErrorResponse.USER_NOT_ENTITLED.toString());
			result = jsonRes.toString();
			return result;
		}
		
		User user = User.getUserFromDB("login", userLogin);
		if(user != null) {
			jsonRes.put("result", ServerErrorResponse.USER_ALREADY_EXISTS.toString());
			result = jsonRes.toString();
			return result;
		}
		
		user = (User)ldap.findUser(userLogin);
		if(user == null) {
			jsonRes.put("result", ServerErrorResponse.MALFORMED_REQUEST.toString());
			result = jsonRes.toString();
			return result;
		}
		if(userRole.equals("admin")) {
			Role adminRole = Role.getRoleFromDB(userRole);
			Admin admin = new Admin(user.getFirst_name(),user.getLast_name(),user.getLogin(),user.getEmail(),adminRole);
			User.addUserToDB(admin);
			
		} else if(userRole.equals("clientAdmin")) {
			try {
				
				if(clientIds == null) {
					jsonRes.put("result", ServerErrorResponse.MALFORMED_REQUEST.toString());
					result = jsonRes.toString();
					return result;
				}
				
				int []client_Ids = new int[clientIds.length()];
				for(int i = 0; i < client_Ids.length; i++) {
					client_Ids[i] = (Integer)clientIds.get(i);
				}
				
				Role clientAdminRole = Role.getRoleFromDB(userRole);
				ClientAdmin clientAdmin = new ClientAdmin(user.getFirst_name(), user.getLast_name(),user.getLogin(),
														  user.getEmail(),clientAdminRole);
				
				ClientAdminProfile clientAdminProfile = new ClientAdminProfile();
				
				clientAdminProfile.setClientAdmin(clientAdmin);
				clientAdminProfile.setEmail(user.getEmail());
				
				if(jsonReq.isNull("defaultClientId")) {
					clientAdminProfile.setDefaultClientId(null);
				} else {
					clientAdminProfile.setDefaultClientId(Integer.parseInt(defaultClientId));
				}
				clientAdmin.setClientAdminProfil(clientAdminProfile);
				User.addUserToDB(clientAdmin);
				
				for(int i = 0; i < client_Ids.length; i++) {
					Client client = Client.getClientFromDB("id_client", client_Ids[i]);
					ClientProfile clientProfile = ClientProfile.
													getClientProfileWithClientAdminsFromDB("id_client_profile", client.getClientProfil().getId_client_profile());
					
					clientProfile.getClientAdmin().add(clientAdmin);
					clientAdminProfile.getClients().add(clientProfile.getClient());
					ClientProfile.updateClientProfileInDB(clientProfile);
				}
				
			} catch(NullPointerException npe) {
				jsonRes.put("result", ServerErrorResponse.INTERNAL_ERROR.toString());
				result = jsonRes.toString();
				return result;
			}
		} else {
			jsonRes.put("result", ServerErrorResponse.MALFORMED_REQUEST.toString());
			result = jsonRes.toString();
			return result;
		}
		
		jsonRes.put("result","OK");
		result = jsonRes.toString();
		return result;
	}
}
